#include "PacketSl651.h"
#include "crc16.h"
#include <string.h>
#include "lib.h"

using namespace controller;
using namespace std;

PacketSl651::PacketSl651() {}
PacketSl651::~PacketSl651() {}

PacketBase *PacketSl651::on_get(char *pdata, int size, void *arg)
{
    uint8_t *d = (unsigned char *)&p;
    uint16_t c = 0;
    for (int i = 0; i < size; i++)
    {

        uint8_t data = pdata[i];
        if (h.len >= SL651_BUFFER_MAX)
            goto DECODE_ERROR;
        d[h.len] = data;
        h.len++;
        switch (h.state)
        {
        // start
        case 0:
            if (data == 0x7E)
            {
                h.state = 0;
                if (h.len == 2)
                {
                    h.state = 1;
                }
            }
            else
                goto DECODE_ERROR;
            break;

        // local address [5]
        case 1:
            if (h.len == 7)
            {
                // 比较地址
                h.state++;
            }
            break;
        // center address
        case 2:
            h.state++;
            break;
        // password
        case 3:
            if (h.len == 10)
            {
                // 比密码
                h.state++;
            }
            break;
        // cmd //hlen //llen
        case 4:
        case 5:
        case 6:
            h.state++;
            break;
        // stx
        case 7:
            h.state++;
            break;
        // 接收数据
        case 8:
        {
            uint16_t dlen = ((p.len >> 8) & 0xFF) | ((p.len & 0xFF) << 8);
            if ((dlen & 0x8000) != 0x8000) // 不是一个下行包，丢掉
            {
                std::cout << ("PacketSl651 不是下行包") << std::endl;
                return NULL;
            }
            dlen &= 0x0FFF;
            if (h.len < (dlen + 14 + 1 + 2))
                break; // data+stop+crc
            else
            {
                uint16_t crc = d[h.len - 2];
                crc <<= 8;
                crc |= d[h.len - 1];
                if (MODBUS_CRC16(d, h.len - 2) == crc)
                {
                    // 接收到一个数据包
                    p.packetlen = h.len;
                    h.len = h.state = 0;
                    p.etx = ((uint8_t *)&p)[p.packetlen - 3];

                    // 转换 local passwd
                    //  h.p.rlocal = bigbcd2hex((u8*)h.p.local,5);
                    LIB::inverse_data_to(p.local, (uint8_t *)&p.rlocal, 5);
                    LIB::inverse_data_to((uint8_t *)&p.passwd, (uint8_t *)&p.rpasswd, 2);
                    // h.p.rpasswd = bigbcd2hex((u8*)&(h.p.passwd),2);
                    return this;
                }
                else
                    goto DECODE_ERROR;
            }
        }
        default:
            goto DECODE_ERROR;
        }
        continue;
    DECODE_ERROR:
        h.len = h.state = 0;
        continue;
    }
    return NULL;
}
int PacketSl651::to_bytes(char *dataout, void **arg)
{
    *arg = NULL;
    if (h.send_size > 0)
    {
        memcpy(dataout, (const void *)&p, h.send_size);
        return h.send_size;
    }
    return 0;
}
string PacketSl651::to_string(string arg)
{
    return "";
}

void PacketSl651::reset_recv()
{
    h.reset();
}

int PacketSl651::build()
{
    return 0;
}
